package com.zsgeek.wisdchain.qutu.base.http;


import android.support.annotation.NonNull;

import com.google.gson.Gson;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Progress;
import com.lzy.okgo.model.Response;
import com.zsgeek.wisdchain.qutu.QuTuApplication;
import com.zsgeek.wisdchain.qutu.base.event.BaseEvent;
import com.zsgeek.wisdchain.qutu.base.event.BaseEventBusHelper;
import com.zsgeek.wisdchain.qutu.base.event.PreferenceHelper;
import com.zsgeek.wisdchain.qutu.base.model.BaseModel;
import com.zsgeek.wisdchain.qutu.tools.LogUtil;

import org.greenrobot.eventbus.EventBus;

import java.io.File;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * @author 王亨彬
 * @date 2018/10/5
 * email：793325917@qq.com
 * 异常知晓:https://www.2cto.com/kf/201706/554775_2.html
 */
public class JsonRequest<T> {
    private JsonRequestCallBack mPufaKuaiOpenView;
    private static long mTaskId = 0;

    public JsonRequest() {
    }

    public JsonRequest(@NonNull JsonRequestCallBack pufaKuaiOpenView) {
        this.mPufaKuaiOpenView = pufaKuaiOpenView;
    }

    public void postJson(final String url, boolean isPost, final String json, final Class clazz) {
        if (QuTuApplication.getInstance().isNetConnect) {
            String taskId = generateRequestId();
//            HttpHeaders headers = new HttpHeaders();
//            headers.put("token", PreferenceHelper.getInstance().getLastUserId());
            String token = PreferenceHelper.getInstance().getLastUserId();
            if (isPost)
                postJson(taskId, url, json, token, clazz);
            else putJson(taskId, url, json, token, clazz);
        } else {
            NotConnect();
        }

    }

    public void getJson(final String url, final Class clazz) {
        if (QuTuApplication.getInstance().isNetConnect) {
            String taskId = generateRequestId();
            getJson(url, clazz, PreferenceHelper.getInstance().getLastUserId(), taskId);
        } else {
            NotConnect();
        }
    }


    private void postJson(final String taskId, final String url, final String json, String headers, final Class clazz) {
        LogUtil.w("url=" + url + "，表单：" + json + ",taskId=" + taskId);
        OkGo.<String>post(url)
                .tag(taskId)
                .headers("token", headers)
                .upJson(json)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        setResoult(clazz, taskId, response);
                    }

                    @Override
                    public void onError(Response<String> response) {
                        handleError(response, taskId);
                    }
                });

    }

    private void putJson(final String taskId, final String url, final String json, String headers, final Class clazz) {
        LogUtil.w("url=" + url + "，表单：" + json + ",taskId=" + taskId);
        OkGo.<String>put(url)
                .tag(taskId)
                .headers("token", headers)
                .upJson(json)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        setResoult(clazz, taskId, response);
                    }

                    @Override
                    public void onError(Response<String> response) {
                        handleError(response, taskId);
                    }
                });
    }

    private void getJson(final String url, final Class clazz, String headers, final String taskId) {
        LogUtil.w("url=" + url + ",taskId=" + taskId);
        OkGo.<String>get(url)
                .tag(taskId)
                .headers("token", headers)
                .execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        setResoult(clazz, taskId, response);
                    }

                    @Override
                    public void onError(Response<String> response) {
                        handleError(response, taskId);
                    }
                });
    }

    //上传图片
    public void uploadFile(final String url, String filekey, final File loadFile,
                           final Class clazz, Consumer<Disposable> consumer, Observer<Progress> observer) {
        if (QuTuApplication.getInstance().isNetConnect) {
            Observable.create(new ObservableOnSubscribe<Progress>() {
                @Override
                public void subscribe(@io.reactivex.annotations.NonNull final ObservableEmitter<Progress> e) throws Exception {
                    String taskId = generateRequestId();
                    LogUtil.w("url=" + url + ",taskId=" + taskId);
                    OkGo.<String>post(url)
                            .tag(taskId)
                            .headers("token", PreferenceHelper.getInstance().getLastUserId())
//                            .params("param1", "paramValue1")
//                            .params("param2", "paramValue2")
                            .params(filekey, loadFile)
                            .execute(new StringCallback() {
                                @Override
                                public void onSuccess(Response<String> response) {
                                    setResoult(clazz, taskId, response);
                                }

                                @Override
                                public void onError(Response<String> response) {
                                    handleError(response, taskId);
                                }
                            });
                }
            }).doOnSubscribe(consumer)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(observer);
        } else {
            NotConnect();
        }
    }

    private void setResoult(Class clazz, String taskId, Response<String> response) {
        if (null != mPufaKuaiOpenView) {
            if (response == null) {
                mPufaKuaiOpenView.showError("Json为null", taskId);
            } else {
                String body = response.body();
                if (body == null) {
                    mPufaKuaiOpenView.showError("数据为null", taskId);
                } else {
                    try {
                        LogUtil.m("线程:" + taskId + ",请求结果：" + body);
                        Object object = new Gson().fromJson(body, clazz);
                        BaseModel baseModel = (BaseModel) object;
                        if (baseModel.getCode() == -100) {
                            EventBus.getDefault().post(new BaseEvent(BaseEventBusHelper.EVENT_LOGOUT, baseModel.getMessage()));
                        } else if (null != mPufaKuaiOpenView) {
                            mPufaKuaiOpenView.showResult(object, taskId);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        mPufaKuaiOpenView.showError("数据解析异常", taskId);
                    }
                }
            }
        }
    }

    private <T> void handleError(Response<T> response, String taskId) {

        if (response == null) return;
        if (null == mPufaKuaiOpenView) return;

        String errorMsg = "网络请求失败，请检查网络";
        try {
            Throwable exception = response.getException();
            if (exception != null) {
                String exceptionMessage = exception.getMessage();
                LogUtil.e("taskId=" + taskId + ",handleError:" + exceptionMessage);
                if (exceptionMessage.contains("failed to connect")) {
                    errorMsg = "failed to connect";
                } else {
                    errorMsg = exceptionMessage.substring(exceptionMessage.indexOf(":") + 1);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        mPufaKuaiOpenView.showError(errorMsg, taskId);

    }

    /**
     * 请求 Bitmap 对象
     *
     * @param url
     */
    public void getJsonBitmap(final String url) {
//        String taskId = generateRequestId();
//        LogUtil.w("url=" + url + ",taskId:" + taskId);
//        OkGo.<Bitmap>get(url)
//                .tag(taskId)
//                .headers("token", PreferenceHelper.getInstance().getLastUserId())
//                .execute(new BitmapCallback() {
//                    @Override
//                    public void onSuccess(com.lzy.okgo.model.Response<Bitmap> response) {
////                        imageView.setImageBitmap(response.body());
//                        if (null != mPufaKuaiOpenView) {
//                            if (response == null) {
//                                mPufaKuaiOpenView.showError("Json为null", taskId);
//                            } else {
//                                mPufaKuaiOpenView.showResult(response.body(), taskId);
//                            }
//                        }
//                    }
//                });
    }


    private void NotConnect() {
        EventBus.getDefault().post(new BaseEvent(BaseEventBusHelper.EVENT_CHECKNETWORK));
    }

    private String generateRequestId() {
        return ++mTaskId + "";
    }
}
